﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PageLayout.cs" company="Anton Frattaroli">
//   Copyright (c) Anton Frattaroli. All rights reserved.
// </copyright>
// <summary>
//   Defines the PageLayout class.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Lidocaine.Data
{
    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Data.SqlClient;
    using System.Globalization;
    using Lidocaine.BusinessObjects;

    /// <summary>
    /// Defines the PageLayout class.
    /// </summary>
    public static class PageLayout
    {
        /// <summary>
        /// Initializes a new instance of the PageLayout class.
        /// </summary>
        /// <param name="pagePath">The virtual path for this page.</param>
        /// <returns>An instantiated PageLayout.</returns>
        public static BusinessObjects.PageLayout Select(string pagePath)
        {
            LazyPageLayout page = null;
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetPageByPath", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PagePath", pagePath);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            rdr.Read();
                            page = new LazyPageLayout();
                            page.Id = Convert.ToInt32(rdr["PageID"], CultureInfo.InvariantCulture);
                            page.Path = pagePath;
                            page.Title = rdr["PageTitle"] != DBNull.Value ? rdr["PageTitle"].ToString() : string.Empty;
                            page.HeaderId = rdr["PageHeader"] != DBNull.Value ? Convert.ToInt32(rdr["PageHeader"], CultureInfo.InvariantCulture) : 0;
                            page.FooterId = rdr["PageFooter"] != DBNull.Value ? Convert.ToInt32(rdr["PageFooter"], CultureInfo.InvariantCulture) : 0;
                            page.LeftNavId = rdr["PageLeftNav"] != DBNull.Value ? Convert.ToInt32(rdr["PageLeftNav"], CultureInfo.InvariantCulture) : 0;
                            page.RightColId = rdr["PageRightCol"] != DBNull.Value ? Convert.ToInt32(rdr["PageRightCol"], CultureInfo.InvariantCulture) : 0;
                            page.TopNavId = rdr["PageTopNav"] != DBNull.Value ? Convert.ToInt32(rdr["PageTopNav"], CultureInfo.InvariantCulture) : 0;
                            page.CssId = rdr["PageCSS"] != DBNull.Value ? Convert.ToInt32(rdr["PageCSS"], CultureInfo.InvariantCulture) : 0;
                            page.JavaScriptId = rdr["PageJS"] != DBNull.Value ? Convert.ToInt32(rdr["PageJS"], CultureInfo.InvariantCulture) : 0;
                            page.ContentId = rdr["PageContent"] != DBNull.Value ? Convert.ToInt32(rdr["PageContent"], CultureInfo.InvariantCulture) : 0;
                        }
                    }
                }
            }

            return page;
        }

        /// <summary>
        /// Initializes a new instance of the PageLayout class.
        /// </summary>
        /// <param name="pageId">The identity of the database table's row referencing this page.</param>
        /// <returns>An instantiated PageLayout.</returns>
        public static BusinessObjects.PageLayout Select(int pageId)
        {
            LazyPageLayout page = null;
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetPageByID", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PageID", pageId);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            rdr.Read();
                            page = new LazyPageLayout();
                            page.Id = pageId;
                            page.Path = rdr["PagePath"].ToString();
                            page.Title = rdr["PageTitle"] != DBNull.Value ? rdr["PageTitle"].ToString() : string.Empty;
                            page.HeaderId = rdr["PageHeader"] != DBNull.Value ? Convert.ToInt32(rdr["PageHeader"], CultureInfo.InvariantCulture) : 0;
                            page.FooterId = rdr["PageFooter"] != DBNull.Value ? Convert.ToInt32(rdr["PageFooter"], CultureInfo.InvariantCulture) : 0;
                            page.LeftNavId = rdr["PageLeftNav"] != DBNull.Value ? Convert.ToInt32(rdr["PageLeftNav"], CultureInfo.InvariantCulture) : 0;
                            page.RightColId = rdr["PageRightCol"] != DBNull.Value ? Convert.ToInt32(rdr["PageRightCol"], CultureInfo.InvariantCulture) : 0;
                            page.TopNavId = rdr["PageTopNav"] != DBNull.Value ? Convert.ToInt32(rdr["PageTopNav"], CultureInfo.InvariantCulture) : 0;
                            page.CssId = rdr["PageCSS"] != DBNull.Value ? Convert.ToInt32(rdr["PageCSS"], CultureInfo.InvariantCulture) : 0;
                            page.JavaScriptId = rdr["PageJS"] != DBNull.Value ? Convert.ToInt32(rdr["PageJS"], CultureInfo.InvariantCulture) : 0;
                            page.ContentId = rdr["PageContent"] != DBNull.Value ? Convert.ToInt32(rdr["PageContent"], CultureInfo.InvariantCulture) : 0;
                        }
                    }
                }
            }

            return page;
        }
        
        /// <summary>
        /// Gets the titles of pages related to this script.
        /// </summary>
        /// <param name="script">The Script subscribed to.</param>
        /// <returns>A readonly list of the titles of the pages referencing this script.</returns>
        public static List<string> SelectAllPageNames(BusinessObjects.Script script)
        {
            List<string> pages = new List<string>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                if (script.ScriptType == ScriptType.Css)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.GetCSSPages", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@ID", script.Id);
                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            if (rdr.HasRows)
                            {
                                while (rdr.Read())
                                {
                                    pages.Add((string)rdr["Name"]);
                                }
                            }
                        }
                    }
                }
                else
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.GetJSPages", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@ID", script.Id);
                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            if (rdr.HasRows)
                            {
                                while (rdr.Read())
                                {
                                    pages.Add((string)rdr["Name"]);
                                }
                            }
                        }
                    }
                }
            }

            return pages;
        }

        /// <summary>
        /// Gets the titles of pages related to this template.
        /// </summary>
        /// <param name="template">The Template subscribed to.</param>
        /// <returns>A readonly list of the titles of the pages referencing this template.</returns>
        public static List<string> SelectAllPageNames(BusinessObjects.Template template)
        {
            List<string> pages = new List<string>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                if (template.Area == TemplateArea.Header)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.GetHeaderPages", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@ID", template.Id);
                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            if (rdr.HasRows)
                            {
                                while (rdr.Read())
                                {
                                    pages.Add((string)rdr["Name"]);
                                }
                            }
                        }
                    }
                }
                else if (template.Area == TemplateArea.Footer)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.GetFooterPages", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@ID", template.Id);
                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            if (rdr.HasRows)
                            {
                                while (rdr.Read())
                                {
                                    pages.Add((string)rdr["Name"]);
                                }
                            }
                        }
                    }
                }
                else if (template.Area == TemplateArea.LeftNav)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.GetLeftNavPages", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@ID", template.Id);
                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            if (rdr.HasRows)
                            {
                                while (rdr.Read())
                                {
                                    pages.Add((string)rdr["Name"]);
                                }
                            }
                        }
                    }
                }
                else if (template.Area == TemplateArea.TopNav)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.GetTopNavPages", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@ID", template.Id);
                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            if (rdr.HasRows)
                            {
                                while (rdr.Read())
                                {
                                    pages.Add((string)rdr["Name"]);
                                }
                            }
                        }
                    }
                }
                else if (template.Area == TemplateArea.RightCol)
                {
                    using (SqlCommand cmd = new SqlCommand("Lidocaine.GetRightColPages", conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        cmd.Parameters.AddWithValue("@ID", template.Id);
                        using (SqlDataReader rdr = cmd.ExecuteReader())
                        {
                            if (rdr.HasRows)
                            {
                                while (rdr.Read())
                                {
                                    pages.Add((string)rdr["Name"]);
                                }
                            }
                        }
                    }
                }
            }

            return pages;
        }

        /// <summary>
        /// Loads all content versions.
        /// </summary>
        /// <param name="page">The PageLayout target.</param>
        /// <returns>A read-only list of page content versions.</returns>
        public static List<BusinessObjects.Content> GetPageContentVersionsInfo(BusinessObjects.PageLayout page)
        {
            List<BusinessObjects.Content> contents = new List<BusinessObjects.Content>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetPageContentBlocks", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@ID", page.Id);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            while (rdr.Read())
                            {
                                ////Data.Content.SelectAll(page);
                                ////contents.Add(new BusinessObjects.Content(Convert.ToInt32(rdr["ID"], CultureInfo.InvariantCulture)));
                            }
                        }
                    }
                }
            }

            return contents;
        }

        public static void SaveAndPublishContent(BusinessObjects.PageLayout page, string content, BusinessObjects.UserProfile profile)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.UpdatePageContent", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PageID", page.Id);
                    cmd.Parameters.AddWithValue("@PageContent", content);
                    cmd.Parameters.AddWithValue("@UserID", profile.Id);
                    cmd.ExecuteNonQuery();
                }
            }
        }

        public static List<Permission> GetPermissionsWithRoleInfo(string path)
        {
            Permission permission = null;
            List<Permission> permissions = new List<Permission>();
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.GetPagePermissionsWithRoleInfo", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PagePath", path);
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        if (rdr.HasRows)
                        {
                            while (rdr.Read())
                            {
                                permission = new Permission();
                                permission.Id = Convert.ToInt32(rdr["PermissionID"], CultureInfo.InvariantCulture);
                                permission.AllowType = rdr["PermissionAllowType"].ToString() == "True" ? PermissionAllowType.Role : PermissionAllowType.UserProfile;
                                permission.AllowId = Convert.ToInt32(rdr["PermissionAllowID"], CultureInfo.InvariantCulture);
                                permission.IsActiveDirectoryRole = rdr["ActiveDirectory"] == DBNull.Value ? false : rdr["ActiveDirectory"].ToString() == "True" ? true : false;
                                permission.Name = rdr["RoleName"] != DBNull.Value ? rdr["RoleName"].ToString() : rdr["UserName"] != DBNull.Value ? rdr["UserName"].ToString() : string.Empty;
                                permissions.Add(permission);
                            }
                        }
                    }
                }
            }

            return permissions;
        }

        /// <summary>
        /// Saves a new PageLayout to the database.
        /// </summary>
        /// <param name="page">The PageLayout to insert.</param>
        /// <returns>The inserted PageLayout with a newly populated Id field.</returns>
        public static BusinessObjects.PageLayout Insert(BusinessObjects.PageLayout page)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.InsertPage", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PagePath", page.Path == null ? string.Empty : page.Path);
                    cmd.Parameters.AddWithValue("@PageTitle", page.Title == null ? string.Empty : page.Title);
                    if (page.HeaderId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageHeader", page.HeaderId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageHeader", DBNull.Value);
                    }

                    if (page.FooterId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageFooter", page.FooterId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageFooter", DBNull.Value);
                    }

                    if (page.RightColId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageRightCol", page.RightColId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageRightCol", DBNull.Value);
                    }

                    if (page.LeftNavId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageLeftNav", page.LeftNavId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageLeftNav", DBNull.Value);
                    }

                    if (page.TopNavId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageTopNav", page.TopNavId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageTopNav", DBNull.Value);
                    }
                    
                    if (page.CssId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageCSS", page.CssId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageCSS", DBNull.Value);
                    }

                    if (page.JavaScriptId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageJS", page.JavaScriptId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageJS", DBNull.Value);
                    }

                    if (page.ContentId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageContent", page.ContentId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageContent", DBNull.Value);
                    }

                    page.Id = Convert.ToInt32(cmd.ExecuteScalar(), CultureInfo.InvariantCulture);
                }
            }

            return page;
        }

        /// <summary>
        /// Saves page updates to database.
        /// </summary>
        /// <param name="page">The PageLayout to update.</param>
        public static void Update(BusinessObjects.PageLayout page)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.UpdatePage", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PageID", page.Id);
                    cmd.Parameters.AddWithValue("@PagePath", page.Path);
                    cmd.Parameters.AddWithValue("@PageTitle", page.Title);
                    if (page.HeaderId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageHeader", page.HeaderId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageHeader", DBNull.Value);
                    }

                    if (page.FooterId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageFooter", page.FooterId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageFooter", DBNull.Value);
                    }

                    if (page.RightColId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageRightCol", page.RightColId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageRightCol", DBNull.Value);
                    }

                    if (page.LeftNavId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageLeftNav", page.LeftNavId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageLeftNav", DBNull.Value);
                    }

                    if (page.TopNavId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageTopNav", page.TopNavId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageTopNav", DBNull.Value);
                    }

                    if (page.CssId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageCSS", page.CssId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageCSS", DBNull.Value);
                    }

                    if (page.JavaScriptId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageJS", page.JavaScriptId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageJS", DBNull.Value);
                    }

                    if (page.ContentId != 0)
                    {
                        cmd.Parameters.AddWithValue("@PageContent", page.ContentId);
                    }
                    else
                    {
                        cmd.Parameters.AddWithValue("@PageContent", DBNull.Value);
                    }

                    cmd.ExecuteNonQuery();
                }
            }
        }

        /// <summary>
        /// Deletes this PageLayout from the database.
        /// </summary>
        /// <param name="page">The PageLayout to delete.</param>
        public static void Delete(BusinessObjects.PageLayout page)
        {
            using (SqlConnection conn = new SqlConnection(Environment.ConnectionString))
            {
                conn.Open();
                using (SqlCommand cmd = new SqlCommand("Lidocaine.DeletePage", conn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@PagePath", page.Path);
                    cmd.ExecuteNonQuery();
                }
            }
        }
    }
}